package com.cy.pj.common.config;

import java.util.LinkedHashMap;

import org.apache.shiro.cache.CacheManager;
import org.apache.shiro.cache.MemoryConstrainedCacheManager;
import org.apache.shiro.mgt.RememberMeManager;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.realm.Realm;
import org.apache.shiro.session.mgt.SessionManager;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.CookieRememberMeManager;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.apache.shiro.web.servlet.SimpleCookie;
import org.apache.shiro.web.session.mgt.DefaultWebSessionManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration //此注解描述的类为spring容器中的一个配置类
public class SpringShiroConfig {
	/**会话Session对象配置:
	 * 	在shiro中用户登陆成功以后会将会话信息写入到session
	 * */
	@Bean   
	public SessionManager sessionManager() {
			 DefaultWebSessionManager sManager=
					 new DefaultWebSessionManager();
			 sManager.setGlobalSessionTimeout(60*60*1000);//配置默认时长
			 return sManager;
	}

	/**配置记住我管理对象:底层同cookie对象将用户信息写到客户端*/
	@Bean
	public RememberMeManager rememberMeManager() {
		CookieRememberMeManager rememberMeManager=new CookieRememberMeManager();
		SimpleCookie cookie=new SimpleCookie("rememberMe");
		cookie.setMaxAge(7*24*60*60);
		rememberMeManager.setCookie(cookie);
		return rememberMeManager;
	}
	
	/**配置shiro中缓存管理器对象*/
	@Bean
	public CacheManager shiroCacheManager() {
		return new MemoryConstrainedCacheManager();
	}
	@Bean //整合第三方的bean资源,通常会采用这样的方式进行配置
	public SecurityManager securityManager(Realm realm,
			                               CacheManager cacheManager,
			                               RememberMeManager rememberMeManager,
			                               SessionManager sessionManager) {
		DefaultWebSecurityManager securityManager=
				new DefaultWebSecurityManager();
		securityManager.setRealm(realm);
		securityManager.setCacheManager(cacheManager);
		securityManager.setRememberMeManager(rememberMeManager);
		securityManager.setSessionManager(sessionManager);
		return securityManager;
	}
	@Bean //<bean id="shiroFilterFactory" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
	public ShiroFilterFactoryBean shiroFilterFactory(SecurityManager securityManager) {
		ShiroFilterFactoryBean factoryBean=new ShiroFilterFactoryBean();
		//设置权限管理器 
		 factoryBean.setSecurityManager(securityManager);
		//设置认证页面
		 factoryBean.setLoginUrl("/doLoginUI");
		 //定义map指定请求过滤规则(哪些资源允许匿名访问,哪些必须认证访问)
		 LinkedHashMap<String,String> map= new LinkedHashMap<>();
		 //静态资源允许匿名访问:"anon"
		 map.put("/bower_components/**","anon");
		 map.put("/build/**","anon");
		 map.put("/dist/**","anon");
		 map.put("/plugins/**","anon");
		 map.put("/user/doLogin","anon");
		 map.put("/doLogout","logout");//logout对应着shiro框架中退出过滤器
		 //除了匿名访问的资源,其它都要认证("authc")后访问
		 //map.put("/**","authc");//假如需要实现记住我功能,这里的过滤器标识使用user
		 map.put("/**", "user");
		 factoryBean.setFilterChainDefinitionMap(map);
		 return factoryBean;
	}
	/**
	 * 	配置Shiro中的Advisor(顾问对象)对象,此对象在spring框架启动时用户告知spring框架要为哪些切入点
	 *	 描述的对象创建代理对象.
	 * @param securityManager
	 * @return
	 */
	@Bean
	public AuthorizationAttributeSourceAdvisor 
	           authorizationAttributeSourceAdvisor(SecurityManager securityManager) {
		       AuthorizationAttributeSourceAdvisor advisor=
			   new AuthorizationAttributeSourceAdvisor();
		advisor.setSecurityManager(securityManager);
		return advisor;
	} 
	/*
	  xml方式的配置: (参考http://shiro.apache.org/spring.html)
      <bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">
        <property name="securityManager" ref="securityManager"/>
      </bean>
	 */
}





